<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
   <script>
    /*
       函数名就是函数的指针，是一个包含对象指针的变量，因为函数就是对象。 
     */
    function sum (a, b) {
        console.log(a+b)
    }
    sum(1,2)  // 3

    // 这段代码的含义就是将sum里指向函数的指针赋值给了another
    const anotherSum = sum

    // 执行函数
    anotherSum(1,2) // 3

    /* JavaScript的函数对象都会暴露一个name属性，是函数的标识符，也就是字符串化的变量名 */
    function foo () {}
    let bar = function () {}
    let baz = () => {}

    console.log(foo.name) // foo
    console.log(bar.name) // bar
    console.log(baz.name) // baz

    // 如果函数使用bind()实例化，或者函数是一个获取函数、设置函数，则函数对象的name属性值前面会加上前缀
    function foo1 () {}
    // 使用bind函数
    console.log(foo.bind(null).name) // bound foo
    // 获取和设置函数
    const dog = {
        age: 1,
        name: 'dog',
        get age() {
            return this.age
        },
        set age(newAge) {
            this.age = newAge
        }
    }
    // 使用set get 函数
    let propertyDescriptor = Object.getOwnPropertyDescriptor(dog, 'age')
    console.log(propertyDescriptor.get.name) // get age
    console.log(propertyDescriptor.set.name) // set age

    // getOwnPropertyDescriptor(obj, prop)获取指定对象的自身属性描述符。自身属性描述符是指直接在对象上定义（而非从对象的原型继承）的描述符。
    // 属性描述符: 该属性是否可写、可读、可配置、是否可修改以及是否可枚举等

    // 关于bind函数的用法。改变函数的this指向并且返回一个新的函数
    const setNum = { 
        a: 1,
        add () {
            console.log(++this.a)
        }
    }
    // 此时的this指向调用它的对象
    setNum.add() // 2
    setNum.add() // 3
    setNum.add() // 4

    // 此时的this指向Windows
    const f = setNum.add
    f() // NaN

    // 使用bind()函数改变this指向, 返回一个新的函数
    const f1 = f.bind(setNum)
    f1() // 5
    f1() // 6
    

   </script> 
</body>
</html>